package com.example.ormsqlsplicingframe1.json;


import com.example.ormsqlsplicingframe1.utlis.StringUtil;
import lombok.SneakyThrows;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

public class JsonObject {

    
    private String json;
    
    private Object object;

    public JsonObject(String json) {
        this.json = json;
    }

    public JsonObject(Object object) {
        this.object = object;
        this.json =  getJson();
    }

    public JsonObject(String json, Object object) {
        this.json = json;
        this.object = object;
    }

    public JsonObject() {
    }

    public String getJson(){
           this.json = getJson(object);
           return this.json;
    }

    public <E> E getObject(Class<E> e) {
        if (json.startsWith(JsonCharacterEnum.LEFT_BRACKETS.getCharacter())){
            List<E> list = getList(e);
            if (list.size() > 0){
                return list.get(0);
            }
            return null;
        }
        return jsonTurnObject(json,e);
    }

    public <E> E getObject(String json ,Class<E> e) {

        if (json.startsWith(JsonCharacterEnum.LEFT_BRACKETS.getCharacter())){
            List<E> list = getList(json,e);
            return list.get(0);
        }

        return jsonTurnObject(json,e);
    }

    public Map<String, Object> getMap(){
        return getMap(json);
    }

    public <E> List<E> getList(Class<E> e){
        return getList(json,e);
    }

    //把json 变成一颗树

    public JsonTree getTree(){

        return getTree(json);
    }

    public JsonTree getTree(String json){

//        if (json.startsWith(JsonCharacterEnum.LEFT_BRACKETS.getCharacter())){
//            List<String> list = getJsonListObject(json);
//            list.parallelStream().forEach(row ->{
//                JsonTree tree = getTree(row);
//            });
//        }
        JsonTree tree = new JsonTree();
        HashMap<String, Object> hashMap = jsonTurnObjectField(json);

        hashMap.keySet().forEach(row -> {

            Object value = hashMap.get(row);

            if (value instanceof Map){
                //返回一个 list
            }else {
                tree.put(row,value);
            }

        });
        return tree;
    }

    public Map<String, Object> getMap(String json){
        if (json.startsWith(JsonCharacterEnum.LEFT_BRACKETS.getCharacter())){
            List<String> list = getJsonListObject(json);
            if (list.size() > 0){
                return jsonTurnObjectField(list.get(0));
            }
            return new HashMap<>();
        }
        return jsonTurnObjectField(json);
    }

    public List<Map<String, Object>> getListMap(){
        if (json.startsWith(JsonCharacterEnum.LEFT_BRACKETS.getCharacter())){
         return getListMap(json);
        }
        return null;
    }

    public List<Map<String, Object>> getListMap(String json){
        List<Map<String, Object>> mapArrayList = new ArrayList<>();
        List<String> list = getJsonListObject(json);

        List<Map<String, Object>> collect = list.parallelStream().map(row -> {
            Map<String, Object> map = getMap(row);
            return map;
        }).collect(Collectors.toList());
        if (collect!= null && collect.size() > 0){
            return collect;
        }

        return mapArrayList;
    }



    @SneakyThrows
    private   String getJson(Object object){
        if (object instanceof  List){
            StringJoiner joiner = new StringJoiner(JsonCharacterEnum.COMMA.getCharacter(), JsonCharacterEnum.LEFT_BRACKETS.getCharacter(), JsonCharacterEnum.RIGHT_BRACKETS.getCharacter());
            ((List<?>) object).forEach( row -> {
                joiner.add(getJson(row));
            });
            return joiner.toString();
        }
        return getJson(object,null);
    }

    /**
     *
     * @param object 目标对象
     * @param asName 别名
     * @return
     */
    @SneakyThrows
    private   String getJson(Object object,String asName) {
        Class<?> aClass = object.getClass();

        StringJoiner joiner = new StringJoiner(
                JsonCharacterEnum.COMMA.getCharacter(),JsonCharacterEnum.LEFT_BRACKET.getCharacter(),JsonCharacterEnum.RIGHT_BRACKET.getCharacter());

        if (!aClass.getSuperclass().equals(Object.class)){
            Object superObj = aClass.getSuperclass().getDeclaredConstructor().newInstance();
            String s = getJson(superObj);
            joiner.add(s);
        }

        for (Field field : aClass.getDeclaredFields()) {
            field.setAccessible(true);

            if (!isBasicAndQuote(field.getType())){

                //TODO 对象转字符串套挂还没处理
                if (field.get(object) != null){



                    joiner.add(getJson(field.get(object),field.getName()));
                }else {
                    joiner.add(JsonCharacterEnum.QUOTATION_MARKS.getCharacter()+field.getName()+JsonCharacterEnum.QUOTATION_MARKS.getCharacter()+JsonCharacterEnum.COLON.getCharacter()+JsonCharacterEnum.LEFT_BRACKET.getCharacter().trim()+JsonCharacterEnum.RIGHT_BRACKET.getCharacter().trim());
                }
            }else {
               Object  value = (field.get(object) != null) ? field.get(object) : "";
                joiner.add(JsonCharacterEnum.QUOTATION_MARKS.getCharacter()+field.getName()+JsonCharacterEnum.QUOTATION_MARKS.getCharacter()+JsonCharacterEnum.COLON.getCharacter()+JsonCharacterEnum.QUOTATION_MARKS.getCharacter()+value+JsonCharacterEnum.QUOTATION_MARKS.getCharacter());
            }
        }

        if (asName == null || asName.equals("")){
            return joiner.toString();
        }

        return JsonCharacterEnum.QUOTATION_MARKS.getCharacter()+asName+JsonCharacterEnum.QUOTATION_MARKS.getCharacter()+JsonCharacterEnum.COLON.getCharacter()+joiner;
    }

    @SneakyThrows
    private    <E> E jsonTurnObject(String json, Class<E> e) {

            //把json处理成一个对象，反射获取map即可
        HashMap<String, Object> map = jsonTurnObjectField(json);

        E newInstance = e.getDeclaredConstructor().newInstance();
        newInstance = (E) objectField(map,newInstance);
        return newInstance;
    }


    /**
     * 对字段赋值
     * @param map
     * @param newInstance 当前对象
     */
    @SneakyThrows
    private Object objectField(HashMap<String, Object> map, Object newInstance) {

        //如果对象继承了父类，对父类对象赋值
        if (!newInstance.getClass().getSuperclass().equals(Object.class)){
           return objectField(map,newInstance.getClass().getSuperclass().getDeclaredConstructor().newInstance());
        }

        Field[] fields = newInstance.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);

            //对对象赋值
            if (!isBasicAndQuote(field.getType())){
                Object o = field.getType().getDeclaredConstructor().newInstance();
                Object value = map.get(field.getName());
                Object object = null;
                if (value != null){
                    object = setField(o,value);
                }
                field.set(newInstance,object);
            }else {
                Object value = map.get(field.getName());
                if (value != null){
                    field.set(newInstance,map.get(field.getName()));
                }else {
                    field.set(newInstance,null);
                }
            }
        }

        return newInstance;
    }

    @SneakyThrows
    public   <E> List<E> getList(String jsonString, Class<E> e){
        List<E> list = new ArrayList<>();
        if (StringUtil.isNotNull(jsonString)){
            //去掉 []
            jsonString = jsonString.substring(1, jsonString.length() - 1).trim();
            if (StringUtil.isNotNull(jsonString)){
                String[] objJson = jsonString.split(",\\s*\\{");

                Arrays.stream(objJson).parallel().forEach(row ->{

                    if (!row.startsWith(JsonCharacterEnum.LEFT_BRACKET.getCharacter())){
                        row = JsonCharacterEnum.LEFT_BRACKET.getCharacter()+row;
                    }
                    if (!row.endsWith(JsonCharacterEnum.RIGHT_BRACKET.getCharacter())){
                        row = JsonCharacterEnum.RIGHT_BRACKET.getCharacter()+row;
                    }
                    list.add(jsonTurnObject(row, e));
                });
            }
        }
        return  list;
    }

    //根据 集合json 转换成一个集合list 对象 json
    public List<String> getJsonListObject(String jsonList){

        if (StringUtil.isNotNull(jsonList)){
            //去掉 []
            jsonList = jsonList.substring(1, jsonList.length() - 1).trim();
            if (StringUtil.isNotNull(jsonList)){
                String[] objJson = jsonList.split(",\\s*\\{");
                List<String> strings = Arrays.stream(objJson).parallel().map(row -> {
                    if (!row.startsWith(JsonCharacterEnum.LEFT_BRACKET.getCharacter())){
                        row = JsonCharacterEnum.LEFT_BRACKET.getCharacter()+row;
                    }
                    if (!row.endsWith(JsonCharacterEnum.RIGHT_BRACKET.getCharacter())){
                        row = JsonCharacterEnum.RIGHT_BRACKET.getCharacter()+row;
                    }
                    return row;
                }).collect(Collectors.toList());

                return strings;
            }
        }
        return new ArrayList<>();
    }


    /**
     *
     * @param object 字段 对象
     * @param map   键值对
     * @return
     */
    @SneakyThrows
    private   Object setField(Object object , Object map) {
        if (map instanceof Map){
            HashMap<String, Object> objectMap = (HashMap<String, Object>) map;
            for (Field field : object.getClass().getDeclaredFields()) {
                field.setAccessible(true);
                if (!isBasicAndQuote(field.getType())){
                    //获取子类对象
                    Object o = field.getType().getDeclaredConstructor().newInstance();
                    Object value = objectMap.get(field.getName());
                    if (value != null){
                        Object setField = setField(o, value);
                        field.set(object,setField);
                    }
                }else {
                    Object value = objectMap.get(field.getName());
                    if (value != null){
                        field.set(object,value);
                    }
                }
            }
        }
        return object;
    }


    //去掉最前面的大括号
    private   String removeBraces(String input) {
        if (input != null && input.startsWith(JsonCharacterEnum.LEFT_BRACKET.getCharacter()) && input.endsWith(JsonCharacterEnum.RIGHT_BRACKET.getCharacter())) {
            return input.substring(1, input.length() - 1).trim();
        }
        return input;
    }


    @SneakyThrows
    private    HashMap<String, Object> jsonTurnObjectField(String json){

        HashMap<String, Object> map = new HashMap<>();

        //大括号内容 处理级联用
        String braces = null;
        //带有key的大括号 用来跳过当前循环
        String bracesKey = null;
        //处理后的key
        String key = "";
        //原本key
        String keyTow = "";

        String  substring = "";


        if (!"".equals(json) && json != null){
            //去空格和 大括号
           // json = json.replaceAll("^\\{|\\}$", "").trim();;
            //如果传进来的当前json数据包含大括号，去掉大括号
            if (json.contains(JsonCharacterEnum.LEFT_BRACKET.getCharacter())){
                json = removeBraces(json);
            }
            for (String s : json.split(JsonCharacterEnum.COMMA.getCharacter())) {

                //如果大括号内容包含当前遍历内容 跳过
                if (StringUtil.isNotNull(bracesKey)){
                    if (bracesKey.contains(s)) continue;
                }

                String[] split = s.split(JsonCharacterEnum.COLON.getCharacter(), 2);
                key = split[0].replace(JsonCharacterEnum.QUOTATION_MARKS.getCharacter(),"").trim();
                keyTow = split[0].trim();
                Object value = null;
                String trim = split[1].replace(JsonCharacterEnum.QUOTATION_MARKS.getCharacter(),"").trim();

                if (trim.contains(JsonCharacterEnum.LEFT_BRACKET.getCharacter())){
                    //获取大括号包含的内容
                    if (StringUtil.isNotNull(substring)){
                        braces = extractContentInBraces(substring);
                    }else {
                        braces = extractContentInBraces(json);
                    }

                    bracesKey = keyTow+JsonCharacterEnum.COLON.getCharacter()+braces;

                    substring = removeExtractedContent(json, braces, key);
                    HashMap<String, Object> hashMap = jsonTurnObjectField(braces);
                    map.put(key,hashMap);
                }else {
                    value = trim;
                }

                if (StringUtil.isNotNull(bracesKey)){
                    if (bracesKey.contains(s)) continue;
                }

                    //保存当前值
                    map.put(key,value);



            }
        }
        return  map;
    }

    private   List<Object> isBasicAndQuoteList = new ArrayList();
      {
        isBasicAndQuoteList.add(String.class);
        isBasicAndQuoteList.add(Integer.class);
        isBasicAndQuoteList.add(Long.class);
        isBasicAndQuoteList.add(Double.class);
        isBasicAndQuoteList.add(Float.class);
        isBasicAndQuoteList.add(Boolean.class);
        isBasicAndQuoteList.add(Byte.class);
        isBasicAndQuoteList.add(int.class);
        isBasicAndQuoteList.add(long.class);
        isBasicAndQuoteList.add(double.class);
        isBasicAndQuoteList.add(float.class);
        isBasicAndQuoteList.add(boolean.class);
        isBasicAndQuoteList.add(byte.class);
    }
    private   boolean isBasicAndQuote(Class<?> type){
        if (isBasicAndQuoteList.contains(type)){
            return true;
        }
       return false;
    }

    //截取大括号内容
    private   String extractContentInBraces(String input) {
        int start = input.indexOf(JsonCharacterEnum.LEFT_BRACKET.getCharacter());
        int end = findMatchingBraceIndex(input, start);
        if (start >= 0 && end > 0) {
            return input.substring(start, end + 1);
        }
        return "";
    }

    private   int findMatchingBraceIndex(String str, int startIndex) {
        int braceCount = 1;
        for (int i = startIndex + 1; i < str.length(); i++) {
            if (str.charAt(i) == '{') {
                braceCount++;
            } else if (str.charAt(i) == '}') {
                braceCount--;
                if (braceCount == 0) {
                    return i;
                }
            }
        }
        return -1;
    }

    /**
     *  字符串截取
     * @param original 截取目标
     * @param extracted 截取内容
     * @return  截取处理后的字符串
     */
    private   String removeExtractedContent(String original, String extracted,String key) {
        int start = original.indexOf(extracted);

        String dome=original.substring(0, start)+original.substring(start+extracted.length());

        int index = dome.indexOf(key);
        String string = dome.substring(0,index).trim() ;

        String trim = dome.substring(index + key.length() + 1).replaceFirst(JsonCharacterEnum.COLON.getCharacter(), "").replaceFirst(JsonCharacterEnum.COMMA.getCharacter(), "").trim();

         String tor = string.substring(0,string.length()-1)+trim;
        return tor ;

    }
}
